<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    /*
    (macro)task，可以理解是每次执行栈执行的代码就是一个宏任务（包括每次从事件队列中获取一个事件回调并放到执行栈中执行）。
    浏览器为了能够使得JS内部(macro)task与DOM任务能够有序的执行，会在一个(macro)task执行结束后，在下一个(macro)task 
    执行开始前，对页面进行重新渲染，流程如下：
    (macro)task->渲染->(macro)task->...
    */
    setTimeout(function () {
      console.log('1');
    });
    new Promise(function (resolve) {
      console.log('2');
      resolve();
    }).then(function () {
      console.log('3');
    }).then(function () {
      console.log('4')
    });
    console.log('5');
// 2 5 3 4 1
    /*
    1.遇到setTimout，异步宏任务，放入宏任务队列中
    2.遇到new Promise，new Promise在实例化的过程中所执行的代码都是同步进行的，所以输出2
    3.而Promise.then中注册的回调才是异步执行的，将其放入微任务队列中
    4.遇到同步任务console.log(‘5’);输出5；主线程中同步任务执行完
    5.从微任务队列中取出任务到主线程中，输出3、 4，微任务队列为空
    6.从宏任务队列中取出任务到主线程中，输出1，宏任务队列为空
    */
  </script>
</body>

</html>